<template>
  <div ref="div">
    setup
    {{ count }}
    {{ double }}
    age:{{ state.age }} props.id: {{ id }}
    <button @click="handleClick">click</button>
    <button @click="changeAge">age</button>
  </div>
</template>

<script>
import {
  ref,
  reactive,
  readonly,
  computed,
  watch,
  watchEffect,
  onMounted,
  onUpdated,
  inject,
} from "vue";
export default {
  // data -> 响应式数据
  props: ["id"],
  setup(props) {
    // 必须要在 setup 里面调用
    const app = inject("app");
    console.log(app);

    // 要获取一个元素的时候 refs
    const div = ref(null);

    onMounted(() => {
      console.log("onMounted1");
    });

    onMounted(() => {
      console.log("onMounted2");
    });

    onUpdated(() => {
      console.log("updated");
    });

    // 没有 this 的概念了
    // 调用不到 this
    console.log(this);
    // props 的获取方式改变了
    // props 是个 readonly 的响应式对象
    console.log(props);
    // 函数
    // 入口——》 composition api 调用入口
    // ref
    // 新加 （不是替换的）
    // 1 -》 对象.value
    // 1 -> 值类型 追踪不到值类型的变化
    // 收集依赖 和触发依赖 -》 能追踪到对象的变化
    // 对象类型 -》 引用类型 -》 proxy
    const count = ref(1);
    console.log(count);

    // 引入类型  ——》 对象
    const state = reactive({
      name: "xiaohong",
      age: 18,
    });

    // 响应式对象 只只能读的
    const readonlyState = readonly({
      age: 18,
    });

    // 计算属性
    const double = computed(() => {
      // return {
      //     get(){

      //     },
      //     set(){

      //     }
      // }
      // 调用对应的依赖
      return count.value * 2;
    });

    // ref ? reactive?
    console.log(double);

    // watch

    // 响应式对象
    watch(count, (val, oldVal) => {
      console.log("new", val);
      console.log("old", oldVal);
    });
    // 接受一个函数
    watch(
      () => count.value,
      (val, oldVal) => {
        console.log("fn-new", val);
        console.log("fn-old", oldVal);
      }
    );

    //
    watchEffect(() => {
      // 获取依赖的响应式数据
      console.log("watchEffect");
      // count
      console.log(count.value);
    });

    //watchEffect vs watch
    // 1. 一上来就调用
    // 2。直接受一个函数

    const handleClick = () => {
      // 心智负担 -》 为什么要用对象包裹一层呢？
      // vue3 它是使用 eslint 来解决这个心智负担的 告诉用户 必须要用 .value 来操作
      count.value++;
    };

    const changeAge = () => {
      console.log(state);
      state.age++;

      readonlyState.age++;
    };

    // ref 和 reactive 都是创建响应式数据的函数
    // ref 是专门处理值类型的 number string boolean
    // ref -> value
    // reactive 处理引用类型 array object
    // 就没有这个限制 直接调用即可

    // ref 和 reactive 我到底应该用哪个呢？
    // const num = 1

    // const info = {
    //     num:1
    // }
    // js
    // vue

    return {
      div,
      double,
      count,
      state,
      handleClick,
      changeAge,
    };
  },
};
</script>

<style></style>
